/**
* Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */

package cgl.narada.wsinfra.deployment.axis.wsr.proxy;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;

import org.apache.axis.message.SOAPEnvelope;

import cgl.narada.wsinfra.WsMessageFlow;
import cgl.narada.wsinfra.exception.DeploymentException;
import cgl.narada.wsinfra.exception.IncorrectExchangeException;
import cgl.narada.wsinfra.exception.MessageFlowException;
import cgl.narada.wsinfra.exception.ParsingException;
import cgl.narada.wsinfra.exception.ProcessingException;
import cgl.narada.wsinfra.exception.UnknownExchangeException;
import cgl.narada.wsinfra.exception.WsFaultException;
import cgl.narada.wsinfra.schemas.addressing.ActionDocument;
import cgl.narada.wsinfra.schemas.addressing.EndpointReferenceType;
import cgl.narada.wsinfra.schemas.addressing.FromDocument;
import cgl.narada.wsinfra.schemas.addressing.ToDocument;
import cgl.narada.wsinfra.schemas.soap.EnvelopeDocument;
import cgl.narada.wsinfra.util.SoapEnvelopeConversion;
import cgl.narada.wsinfra.util.SoapMarshaller;
import cgl.narada.wsinfra.util.SoapMessageAlteration;
import cgl.narada.wsinfra.wsa.AddressingHeaders;
import cgl.narada.wsinfra.wsa.ParseWsaHeaders;
import cgl.narada.wsinfra.wsa.WsaEprCreator;
import cgl.narada.wsinfra.wsa.WsaProcessingFactory;
import cgl.narada.wsinfra.wsr.WsrNodeUtils;
import cgl.narada.wsinfra.wsr.WsrProcessingFactory;
/**
 * @author Damodar Yemme
 * $Date: 2005/09/1 18:49:28 $
 * $Revision: 1.1 $
 * This class contains both Source and Sink web service combined. It will 
 * process both requests coming from Network and Application client. It resides
 * in One machine and talks to other proxy service installed on diferent machine
 */ 
public class WsrProxyService {
	 private String moduleName = "WsrProxyService  ";	 
	 
	 private WsaEprCreator eprCreator;	 
	 private EndpointReferenceType sinkEpr;
	 private String sinkAddress;
	 private String sourceAddress;
	 private String targetServiceAddress;	
	 private WsrNodeUtils wsrNodeUtils;
	 private WsrSinkProxyHelper wsrSinkProxyHelper;
	 private WsrSourceProxyHelper wsrSourceProxyHelper;
	 private String methodName;
	 
	public WsrProxyService() throws DeploymentException {
		sourceAddress = WsrProxyServicesFactory.getSourceAddress();
	    sinkAddress = WsrProxyServicesFactory.getSinkAddress();
	    wsrSinkProxyHelper = new WsrSinkProxyHelper();
	    wsrSourceProxyHelper = new WsrSourceProxyHelper();
	    targetServiceAddress =WsrProxyServicesFactory.getTargetServiceAddress();
	    eprCreator = WsaProcessingFactory.getWsaEprCreator();
	    wsrNodeUtils = WsrProcessingFactory.getWsrNodeUtils();
	    methodName = WsrProxyServicesFactory.getMethodName();
	}
	/**
	   * Handles reliable messaging. Takes messages, negotiates with other 
	   * endpoint proxy services and sends the message
	   */
	  public void wsInfraProcessMethod(SOAPEnvelope req, SOAPEnvelope resp) 
	  throws WsFaultException, ParsingException, ProcessingException {
	  	try {
	  	   SOAPMessage soapMessage = SoapMarshaller.unmarshallSoapMessage
	  	                      (req.toString().getBytes()); 
	        System.out.println("*******************************************\n");
	  	    System.out.println(moduleName+"Envelope in Proxy service \n\n"+req);
	  	    System.out.println("*******************************************");
	        SoapEnvelopeConversion soapEnvelopeConversion = 
	        	                         SoapEnvelopeConversion.getInstance();
	        EnvelopeDocument envelopeDocument = soapEnvelopeConversion
	                .getEnvelopeDocument(soapMessage);
  
		 QName qName = new QName("http://docs.oasis-open.org/wss/2004/01/oasis"+
		 		"-200401-wss-wssecurity-secext-1.0.xsd","Security");      
      		SoapMessageAlteration soapMessageAlteration = 
      									SoapMessageAlteration.getInstance();
      		soapMessageAlteration.removeFromSoapHeader(envelopeDocument,qName);

	        String from = null;
	        String to = null;
	        ToDocument toDocument = null;
	        FromDocument fromDocument = null;
	        AddressingHeaders addressingHeaders = null;
	        ParseWsaHeaders parseWsaHeaders = WsaProcessingFactory
	                .getParseWsaHeaders();

	        try {
	            toDocument = parseWsaHeaders.getTo(envelopeDocument);
	            fromDocument = parseWsaHeaders.getFrom(envelopeDocument);
	            addressingHeaders = parseWsaHeaders
	                    .getAddressingHeaders(envelopeDocument);
	        } catch (ParsingException parseEx) {
	            // Ignore this exception.
	            System.out.println("Problems parsing the envelope"
	                    + parseEx.toString());
	        }
	        String action = null;
	        ActionDocument actionDocument = null;
	        try {
	            actionDocument = addressingHeaders.getAction();
	            if (actionDocument == null) {
	                String reason = moduleName
	                        + "Action missing. Processor only deals with "
	                        + "WS-Reliability exchanges.";
	            }

	            if (actionDocument != null) {
	                action = actionDocument.getAction().getStringValue();
	            }
	        } catch (Exception e) {
	            System.out.println(moduleName
	                    + "Exception in Processing action " + e);
	        }

	        if (toDocument == null) {
	            to = "";
	        } else {
	            to = toDocument.getTo().getStringValue();

	        }
	        if (fromDocument == null) {
	            from = "";
	        } else {
	            from = fromDocument.getFrom().getAddress().getStringValue();
	        }
	        
	        boolean continueProcessing=false;
	        try {
	        // Call SinkNode first
	        if (!to.equalsIgnoreCase(sinkAddress)) {
	            System.out.println
	            		("**Received SOAPMessage (SINK) from Application**");
	            continueProcessing = wsrSinkProxyHelper.getProcessor().
	          processExchange(envelopeDocument, WsMessageFlow.FROM_APPLICATION);
	        }
	        else{
	            System.out.println
	            ("***Received SOAPMessage (SINK) from Network*****");
	            continueProcessing = wsrSinkProxyHelper.getProcessor().
	            processExchange(envelopeDocument, WsMessageFlow.FROM_NETWORK);
	        }
	      }catch (Exception e) {
	           System.out.println(moduleName + e.toString());
	      }
	        //Call Source node
	      if (!from.equalsIgnoreCase(targetServiceAddress)) {
		 System.out.println("from Address"+from);
		 System.out.println("source Address"+sourceAddress);
	        if (from.equalsIgnoreCase(sourceAddress)) {
	            System.out.println
	            ("**Received SOAPMessage (SOURCE) from Application**");
	            continueProcessing = wsrSourceProxyHelper.getProcessor().
	          processExchange(envelopeDocument, WsMessageFlow.FROM_APPLICATION);
	        }
	        else{
	            System.out.println
	            ("***Received SOAPMessage (SOURCE) from Network*****");
	            continueProcessing = wsrSourceProxyHelper.getProcessor()
	            .processExchange(envelopeDocument, WsMessageFlow.FROM_NETWORK);
	        }
	      }
	  	} catch (UnknownExchangeException ex) {
	        System.out
	                .println(moduleName + " UnknownExchangeException : " + ex);
	    } catch (IncorrectExchangeException ex) {
	        System.out.println(moduleName + " IncorrectExchangeException : "
	                + ex);
	    } catch (MessageFlowException ex) {
	        System.out.println(moduleName + " MessageFlowException : " + ex);
	    } catch (Exception ex) {
	        System.out.println(moduleName + " Exception in processMessage() "
	                + ex);
	    }   
	  }	
}
